package com.zl.payment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zl.payment.entity.*;
import com.zl.payment.mapper.*;
import com.zl.payment.service.IMonthBillService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zl.payment.service.IOverdueBillService;
import com.zl.payment.service.IOverdueRecordService;
import com.zl.payment.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  服务实现类
 *  月账单 ： 即出账账单 ，包含消费、历史、分期账单。历史账单需要考虑到违约金和利息的问题。
 *
 * </p>
 *
 * @author 黄军鹏
 * @since 2020-07-17
 */
@Service
public class MonthBillServiceImpl extends ServiceImpl<MonthBillMapper, MonthBill> implements IMonthBillService {
    private final int[] days = {1,3,6,9,13,16,21,26,28};//可能的出账日
    private final String CREDIT_CARD_ID = "CREDIT_CARD_ID";
    private final String BILLING_MONTH = "BILLING_MONTH";
    @Autowired
    private ConsumptionBillMapper consumptionBillMapper;
    @Autowired
    private HistoryBillMapper historyBillMapper;
    @Autowired
    private InstallmentBillMapper installmentBillMapper;
    @Autowired
    private MonthBillMapper monthBillMapper;
    @Autowired
    private IOverdueBillService overdueBillService;
    @Autowired
    private IOverdueRecordService overdueRecordService;

/**
 * 获取出账日在当前日期的信用卡列表。
 * @return
 */
   /* public List<CreditCardMessage> getCardsByDate(){
        int day = DateUtils.getDayOfMonth();
        if (!Arrays.asList(days).contains(day)) {
            return null;
        }
        //调用服务查询当前出账日的信用卡账号。
        List<CreditCardMessage> list = new ArrayList<>();
        list.add(new CreditCardMessage("123451","6226200509123456","1","hah","jihuo",new BigDecimal("5000"),16,new BigDecimal("10000")));
        list.add(new CreditCardMessage("123452","6226200509223456","1","hah","jihuo",new BigDecimal("5000"),16,new BigDecimal("10000")));
        list.add(new CreditCardMessage("123453","6226200509323456","1","hah","jihuo",new BigDecimal("5000"),16,new BigDecimal("10000")));
        list.add(new CreditCardMessage("123454","6226200509423456","1","hah","jihuo",new BigDecimal("5000"),16,new BigDecimal("10000")));
        list.add(new CreditCardMessage("123455","6226200509523456","1","hah","jihuo",new BigDecimal("5000"),16,new BigDecimal("10000")));
        list.add(new CreditCardMessage("123456","6226200509623456","1","hah","jihuo",new BigDecimal("5000"),16,new BigDecimal("10000")));
        return list;
    }*/

    public ConsumptionBill getConsumptionBill(String creditCardId,String month){
        QueryWrapper<ConsumptionBill> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CREDIT_CARD_ID,creditCardId);
        queryWrapper.eq(BILLING_MONTH,month);
        ConsumptionBill consumptionBill = consumptionBillMapper.selectOne(queryWrapper);
        return consumptionBill;
    }

    public List<InstallmentBill> getInstallments(String creditCardId,String  month){
        QueryWrapper<InstallmentBill> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CREDIT_CARD_ID,creditCardId);
        queryWrapper.eq(BILLING_MONTH,month);
        List<InstallmentBill> installmentBills = installmentBillMapper.selectList(queryWrapper);
        return installmentBills;
    }
    
    public HistoryBill getHistoryBill(String creditCardId){
        QueryWrapper<HistoryBill> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CREDIT_CARD_ID,creditCardId);
        HistoryBill historyBill = historyBillMapper.selectOne(queryWrapper);
        return historyBill;
    }
    
    public boolean generatorMonthBill(String creditCardId){
        String month = DateUtils.billMonth();
        MonthBill monthBill = new MonthBill();
        monthBill.setCreditCardId(creditCardId).setBillMonth(month).setBillStatus(0).setBillDate(DateUtils.today());
        //消费账单计算
        ConsumptionBill consumptionBill = getConsumptionBill(creditCardId, month);
        monthBill.setConsumSimpleAmount(consumptionBill.getSimpleConsumAmount());
        monthBill.setConsumInstallmentAmount(consumptionBill.getInstallmentConsumAmount());
        //修改消费账单状态
        /*UpdateWrapper<ConsumptionBill> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ACCOUNT_STATUS",1);
        int result = consumptionBillMapper.update(consumptionBill, updateWrapper);*/
        consumptionBill.setAccountStatus(1);
        int result = consumptionBillMapper.updateById(consumptionBill);
        while (result!=1){
            throw new RuntimeException("消费账单状态修改失败！");
        }
        //历史账单计算
        HistoryBill historyBill = getHistoryBill(creditCardId);
        BigDecimal remainingBillAmount = historyBill.getRemainingBillAmount();
        int intervalDays = DateUtils.getIntervalDays(historyBill.getUpdateTime());
        BigDecimal interest = remainingBillAmount.multiply(new BigDecimal("0.0005")).multiply(new BigDecimal(String.valueOf(intervalDays))).add(historyBill.getInitialInterest());
        monthBill.setHistoryAmount(remainingBillAmount).setHistoryInterest(interest);
        //修改历史账单
        int rs = historyBillMapper.updateById(new HistoryBill(historyBill.getHistoryBillId(), historyBill.getCreditCardId(),
               DateUtils.today(), new BigDecimal("0"), new BigDecimal("0"), new BigDecimal("0"), new BigDecimal("0"), new BigDecimal("0")));
        while (rs!=1){
            throw new RuntimeException("历史账单状态修改失败！");
        }
        //分期账单计算
        List<InstallmentBill> installments = getInstallments(creditCardId, month);
        BigDecimal installment = new BigDecimal("0");
        BigDecimal rateNum = new BigDecimal("0");
        for (InstallmentBill installmentBill : installments) {
            installment  = installment.add(installmentBill.getBillAmount());
            rateNum = rateNum.add(installmentBill.getBillRatenum());
            installmentBill.setBillStatus(1);
            installmentBillMapper.updateById(installmentBill);
        }
        String substring = UUID.randomUUID().toString().substring(0, 16);
        monthBill.setInstallmentAmount(installment).setInstallmentRatenum(rateNum).setBillId(substring);
        int  i = monthBillMapper.insert(monthBill);
        return i==1;
    }
    
    public MonthBill getMonthBill(String creditCardId){
        String month = DateUtils.billMonth();
        QueryWrapper<MonthBill> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CREDIT_CARD_ID,creditCardId);
        queryWrapper.eq("BILL_MONTH",month);
        MonthBill monthBill = monthBillMapper.selectOne(queryWrapper);
        return monthBill;
    }
    //全额还款的还款数
    public BigDecimal getTotalAmount(MonthBill monthBill){
        BigDecimal totalAmount = monthBill.getConsumInstallmentAmount().add(monthBill.getConsumSimpleAmount()).add(monthBill.getInstallmentAmount())
                .add(monthBill.getInstallmentRatenum()).add(monthBill.getHistoryAmount()).add(monthBill.getHistoryInterest());
        return totalAmount;
    }
    
    //可分期还款的最大金额计算
    public BigDecimal getInstallmentAmount(MonthBill monthBill){
        BigDecimal installmentAmount = monthBill.getConsumSimpleAmount().add(monthBill.getHistoryAmount()).add(monthBill.getHistoryInterest());
        return installmentAmount.multiply(new BigDecimal("0.9"));
    }
    //去除最大金额后剩余应还金额
    public BigDecimal restAmount(MonthBill monthBill,BigDecimal actuallyInstallmentAmount){
        return getTotalAmount(monthBill).subtract(actuallyInstallmentAmount);
    }
    //最小还款额
    public BigDecimal leastAmont(MonthBill monthBill){
        BigDecimal simpleAmount = monthBill.getConsumSimpleAmount().add(monthBill.getHistoryAmount()).add(monthBill.getHistoryInterest());
        BigDecimal multiply = simpleAmount.multiply(new BigDecimal("0.1"));
        System.out.println(multiply.floatValue());
        System.out.println(monthBill.getInstallmentAmount().add(monthBill.getInstallmentRatenum()).add(monthBill.getConsumInstallmentAmount()).floatValue());
        return  monthBill.getInstallmentAmount().add(monthBill.getInstallmentRatenum()).add(monthBill.getConsumInstallmentAmount()).add(multiply);
    }
    //逾期账单处理
    public List<MonthBill> overdueBills(){
        Date date = DateUtils.billDate();
        QueryWrapper<MonthBill> queryWrapper = new QueryWrapper<>();
        queryWrapper.lt("BILL_DATE", date);
        queryWrapper.eq("BILL_STATUS",0);
        List<MonthBill> monthBills = monthBillMapper.selectList(queryWrapper);
        return monthBills;
    }
    //转为逾期账单
    public boolean transforOverdueBill(List<MonthBill> monthBills){
        List<OverdueBill> overdueBills = new ArrayList<>();
        List<OverdueRecord> records = new ArrayList<>();
        int count = 0;
        for (MonthBill monthBill : monthBills) {
            BigDecimal totalSimpleAmount = monthBill.getConsumSimpleAmount().add(monthBill.getHistoryAmount()).add(monthBill.getHistoryInterest());
            BigDecimal totalInstallAmount = monthBill.getConsumInstallmentAmount().add(monthBill.getInstallmentAmount()).add(monthBill.getInstallmentRatenum());
            BigDecimal leastAmont = leastAmont(monthBill);//最低还款额
            System.out.println("最低还款额"+leastAmont);
            BigDecimal lateFee = leastAmont.multiply(new BigDecimal("0.05"));//滞纳金
            String billId = UUID.randomUUID().toString().replaceAll("-","").substring(0,15);
            String recordId = UUID.randomUUID().toString().replaceAll("-","").substring(0,15);
            OverdueBill overdueBill = new OverdueBill(billId, monthBill.getCreditCardId(), monthBill.getBillId(), totalInstallAmount,
                    totalInstallAmount, totalSimpleAmount, totalSimpleAmount, lateFee, DateUtils.today(), 0);
            OverdueRecord overdueRecord = new OverdueRecord(recordId, monthBill.getCreditCardId(), billId, DateUtils.today(), 0, null, null);
            monthBill.setBillStatus(4);
            int i = monthBillMapper.updateById(monthBill);
            if (i==1) count++;
            System.out.println(i);
            overdueBills.add(overdueBill);
            records.add(overdueRecord);
        }
        boolean saveBatch = overdueBillService.saveBatch(overdueBills);
        boolean batch = overdueRecordService.saveBatch(records);
        if (saveBatch&&batch){
            System.out.println("处理了"+count+"条逾期账单");
            return true;
        }
        System.out.println("没有逾期账单");
        return false;
        }
    
}
